package com.alibaba.cola.statemachine;

import com.alibaba.cola.statemachine.exception.StateMachineException;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * StateMachineFactory
 * 状态机工厂类
 *
 * @author Frank Zhang
 * @date 2020-02-08 10:21 PM
 */
public class StateMachineFactory {
    private final static Map<String /* machineId */, StateMachine<?, ?, ?>> stateMachineMap = new ConcurrentHashMap<>();

    /**
     * 注册一个状态机
     *
     * @param stateMachine 状态机
     * @param <S>          状态
     * @param <E>          事件
     * @param <C>          上下文
     */
    public static <S, E, C> void register(StateMachine<S, E, C> stateMachine) {
        String machineId = stateMachine.getMachineId();
        if (stateMachineMap.get(machineId) != null) {
            throw new StateMachineException("The state machine with id [" + machineId + "] is already built, no need to build again");
        }
        stateMachineMap.put(stateMachine.getMachineId(), stateMachine);
    }

    /**
     * 通过状态机id获取状态机
     *
     * @param machineId 状态机id
     * @param <S>       状态
     * @param <E>       事件
     * @param <C>       上下文
     * @return 状态机
     */
    public static <S, E, C> StateMachine<S, E, C> get(String machineId) {
        StateMachine stateMachine = stateMachineMap.get(machineId);
        if (stateMachine == null) {
            throw new StateMachineException("There is no stateMachine instance for " + machineId + ", please build it first");
        }
        return stateMachine;
    }
}
